#include "occipool.hpp"
#include "occiservice.hpp"
#include <boost/date_time/posix_time/posix_time.hpp>
#include <string>
#include <sstream>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/split.hpp>
#include <vector>
using std::vector;
using std::stringstream;
using namespace com_oocl_monitor::service;
using namespace com_oocl_monitor::domain;
using std::string;
using namespace boost::posix_time;

OcciService::OcciService(OcciPool *pool)
	: _pool(pool){
}

OcciService::~OcciService() {
}

DataCollection * OcciService::perform(const Profile profile, const ptime startTime, const ptime endTime) {
	DataCollection *data = new DataCollection;
	string start, end;
	time_facet *f = new time_facet("%Y%m%d %H:%M:%S");
	stringstream ss;
	ss.imbue(std::locale(std::cout.getloc(), f));
	Connection *con=nullptr;
	Statement *stmt = nullptr;
	ResultSet *rs = nullptr;
	string sql;
	if (profile._dataDirection== "INBOUND") {
		ss.clear();
		ss.str("");
		ss << startTime;
		getline(ss, start);
		boost::trim(start);
		ss.clear();
		ss.str("");
		ss << second_clock::local_time();
		getline(ss, end);
		boost::trim(end);
		sql += "select v.message_location,to_char(v.update_time,'YYYY-MM-DD HH24:MI:SS'),"
			"v.sourcefile_size from dmtp_auditrecord v where v.update_time<= to_date('";
		sql += end+ "','YYYYMMDD HH24:MI:SS') and v.profile_name in (";
	} else {
		ss.clear();
		ss.str("");
		ss << startTime;
		getline(ss, start);
		boost::trim(start);
		ss.clear();
		ss.str("");
		ss << endTime;
		getline(ss, end);
		boost::trim(end);
		sql += "select v.TARGETMESSAGE_LOCATION,to_char(v.update_time,'YYYY-MM-DD HH24:MI:SS'),v.TRANSFORMEDMESSAGE_SIZE"
			" from dmtp_auditrecord v where v.update_time >= to_date('";
		sql += start+ "','YYYYMMDD HH24:MI:SS') and v.update_time<= to_date('";
		sql += end+ "','YYYYMMDD HH24:MI:SS') and v.profile_name in (";
	}
	vector<string> profiles=split(profile._profileName);
	int flag=0;
	for (auto it = profiles.begin(); it != profiles.end(); ++it) {
		if(flag!=0)
			sql+=",";
		flag=1;
		sql += "'" + (*it) + "'";
	}
	sql += ")";
	try {
		con=_pool->getConnection();
		stmt = con->createStatement(string(sql.begin(), sql.end()));
		stmt->setPrefetchRowCount(1000);
		rs = stmt->executeQuery();
		while (rs->next()) {
			string fileName = rs->getString(1);
			string dateTime = rs->getString(2);
			size_t fileSize = rs->getInt(3);
			data->insert(fileName, ValueType(dateTime, fileSize));
		}
	} catch (const SQLException &e) {
		if (rs != nullptr)
			stmt->closeResultSet(rs);
		if (stmt != nullptr)
			con->terminateStatement(stmt);
		_pool->releaseConnection(con);
		delete(data);
		throw DbException();
	}
	stmt->closeResultSet(rs);
	con->terminateStatement(stmt);
	_pool->releaseConnection(con);
	//
	return data;
}

vector<string> OcciService::split(const string& str) const {
	string ps = str;
	vector<string> profiles;
	size_t last = 0;
	size_t index = ps.find_first_of(",", last);
	while (index != string::npos) {
		profiles.push_back(ps.substr(last, index - last));
		last = index + 1;
		index = ps.find_first_of(",", last);
	}
	if (index - last > 0)
		profiles.push_back(ps.substr(last, index - last));
	return profiles;
}

